package com.recipedb.sprint.util;

import com.recipedb.sprint.entity.LlmOutputs;
import com.recipedb.sprint.repository.LlmOutputsRepository;
import com.recipedb.sprint.repository.SessionsRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.stream.MapRecord;
import org.springframework.data.redis.connection.stream.ReadOffset;
import org.springframework.data.redis.connection.stream.StreamOffset;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

@Slf4j
@Component
public class LlmOutputConsumer {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private LlmOutputsRepository llmOutputsRepository;

    @Autowired
    private SessionsRepository sessionsRepository;

    // 表格行模式匹配
    private static final Pattern TABLE_ROW_PATTERN = Pattern.compile("\\|.*?\\|");

    /**
     * 专门为最终响应数据设计的格式化
     */
    public String formatForFinalAnswer(String content) {
        if (content == null || content.isEmpty()) return content;

        log.info("🔧 开始最终响应格式化");

        // 1. 先使用现有的基础清理
        content = cleanContentImproved(content);
        log.info("✅ 基础清理完成");

        // 2. 转换所有表格为自然语言
        content = convertAllTablesToNaturalLanguage(content);

        // 3. 响应数据专用格式化
        content = content.replaceAll("\\s+([，。！？；])", "$1");
        content = content.replaceAll("([，。！？；])\\s+", "$1");
        content = content.replaceAll("\\s*-\\s*", "-");
        content = content.replaceAll("\\*\\*\\s*(.*?)\\s*\\*\\*", "**$1**");

        // 4. 优化段落结构
        content = optimizeParagraphStructure(content);

        log.info("🎉 最终响应格式化完成");
        return content.trim();
    }

    /**
     * 转换所有表格为自然语言 - 完全重写版本
     */
    private String convertAllTablesToNaturalLanguage(String content) {
        if (content == null || !content.contains("|")) {
            return content;
        }

        log.info("🔄 开始表格转换，内容长度: {}", content.length());

        // 使用更可靠的方式分割行
        String[] lines = content.split("\\r?\\n");
        log.info("分割后行数: {}", lines.length);

        StringBuilder result = new StringBuilder();
        List<String> currentTable = new ArrayList<>();
        boolean inTable = false;
        String currentTableTitle = "";

        for (int i = 0; i < lines.length; i++) {
            String line = lines[i];
            String trimmedLine = line.trim();

            // 跳过空行
            if (trimmedLine.isEmpty()) {
                if (inTable) {
                    currentTable.add(line); // 保留表格内的空行
                } else {
                    result.append(line).append("\n");
                }
                continue;
            }

            // 检测表格开始 - 只检查包含表格关键词的行
            if (!inTable && isPotentialTableLine(trimmedLine) && isTableHeader(trimmedLine)) {
                log.info("🎯 检测到表格开始，行 {}: {}", i, trimmedLine.length() > 50 ? trimmedLine.substring(0, 50) + "..." : trimmedLine);
                inTable = true;
                currentTable.clear();
                currentTable.add(line); // 保存原始行，包括格式

                // 检查前一行是否是标题
                if (i > 0) {
                    String previousLine = lines[i-1].trim();
                    if (isTableTitle(previousLine)) {
                        currentTableTitle = previousLine;
                        // 从结果中移除刚添加的标题行
                        if (result.length() > 0) {
                            String currentResult = result.toString();
                            String[] resultLines = currentResult.split("\\r?\\n");
                            if (resultLines.length > 0) {
                                result.setLength(0);
                                for (int j = 0; j < resultLines.length - 1; j++) {
                                    result.append(resultLines[j]).append("\n");
                                }
                            }
                        }
                    }
                }
                continue;
            }

            // 处理表格内的行
            if (inTable) {
                // 如果是表格行或分隔行，继续收集
                if (trimmedLine.contains("|") || isTableSeparator(trimmedLine)) {
                    currentTable.add(line);
                    log.debug("添加到表格，当前表格行数: {}", currentTable.size());
                } else {
                    // 非表格行，结束当前表格
                    log.info("📊 表格结束，处理收集的表格，行数: {}", currentTable.size());
                    processTable(result, currentTable, currentTableTitle);

                    currentTable.clear();
                    inTable = false;
                    currentTableTitle = "";

                    // 添加当前非表格行
                    result.append(line).append("\n");
                }
            } else {
                // 非表格行
                result.append(line).append("\n");
            }
        }

        // 处理最后可能剩余的表格
        if (!currentTable.isEmpty()) {
            log.info("📊 处理最后剩余的表格，行数: {}", currentTable.size());
            processTable(result, currentTable, currentTableTitle);
        }

        String converted = result.toString();
        log.info("✅ 表格转换完成，结果长度: {}", converted.length());
        return converted;
    }

    /**
     * 处理表格内容
     */
    private void processTable(StringBuilder result, List<String> tableLines, String tableTitle) {
        if (tableLines.size() >= 2) {
            String naturalText = convertTableToNaturalLanguage(tableLines, tableTitle);
            result.append(naturalText);
        } else {
            log.warn("❌ 表格行数不足: {}，回退原始内容", tableLines.size());
            // 回退原始内容
            for (String tableLine : tableLines) {
                result.append(tableLine).append("\n");
            }
        }
    }

    /**
     * 判断是否为潜在表格行
     */
    private boolean isPotentialTableLine(String line) {
        return line.contains("|") &&
                (line.contains("车型") || line.contains("定位") || line.contains("官网") ||
                        line.contains("价格") || line.contains("落地") || line.contains("推荐"));
    }

    /**
     * 判断是否为表格标题
     */
    private boolean isTableTitle(String line) {
        return line.matches(".*###.*") ||
                line.matches(".*\\d+\\..*") ||
                line.matches(".*核心推荐.*") ||
                line.matches(".*推荐.*摘要.*");
    }

    /**
     * 简化的表格表头检测逻辑 - 修复版本
     */
    private boolean isTableHeader(String line) {
        if (!line.contains("|")) return false;

        // 移除保护标记进行检查
        String cleanLine = line.replace("__PIPE_SPACE__", " |")
                .replace("__SPACE_PIPE__", "| ")
                .replace("__PIPE_DASH__", "|-")
                .replace("__DASH_PIPE__", "-|");

        log.debug("检查表格表头，行: {}", cleanLine.length() > 100 ? cleanLine.substring(0, 100) + "..." : cleanLine);

        // 检查是否包含表头关键词组合
        boolean hasModel = cleanLine.contains("车型");
        boolean hasPositioning = cleanLine.contains("核心定位") || cleanLine.contains("定位");
        boolean hasWebsite = cleanLine.contains("官网");
        boolean hasPrice = cleanLine.contains("落地价") || cleanLine.contains("价格");
        boolean hasRecommendation = cleanLine.contains("推荐");

        // 需要至少包含车型和另外一个关键词
        boolean isHeader = hasModel && (hasPositioning || hasWebsite || hasPrice || hasRecommendation);

        log.debug("表头检测结果: {} (车型: {}, 定位: {}, 官网: {}, 价格: {}, 推荐: {})",
                isHeader, hasModel, hasPositioning, hasWebsite, hasPrice, hasRecommendation);
        return isHeader;
    }

    /**
     * 提取表格标题
     */
    private String extractTableTitle(String previousContent) {
        String[] previousLines = previousContent.split("\n");
        if (previousLines.length > 0) {
            String lastLine = previousLines[previousLines.length - 1].trim();
            // 如果是标题行（包含###或数字序号）
            if (lastLine.matches(".*###.*") || lastLine.matches(".*\\d+\\..*")) {
                return lastLine;
            }
        }
        return "";
    }

    /**
     * 将表格转换为自然语言 - 修复版本
     */
    private String convertTableToNaturalLanguage(List<String> tableLines, String tableTitle) {
        log.info("🔄 开始转换表格，总行数: {}", tableLines.size());

        if (tableLines.size() < 2) {
            log.warn("❌ 表格行数不足: {}", tableLines.size());
            return String.join("\n", tableLines) + "\n";
        }

        // 过滤掉分隔行，只保留数据行
        List<String> dataLines = new ArrayList<>();
        for (String line : tableLines) {
            String trimmed = line.trim();
            if (!isTableSeparator(trimmed) && trimmed.contains("|")) {
                dataLines.add(line);
            }
        }

        log.info("📋 过滤后数据行数: {}", dataLines.size());

        if (dataLines.size() < 2) {
            log.warn("❌ 过滤后表格数据行不足");
            return String.join("\n", tableLines) + "\n";
        }

        // 获取表头
        List<String> headers = parseTableRow(dataLines.get(0));
        log.info("📖 表格表头: {}", headers);

        StringBuilder result = new StringBuilder();

        // 添加表格标题
        if (!tableTitle.isEmpty()) {
            result.append(tableTitle).append("\n\n");
        }

        // 判断表格类型并相应处理
        if (headers.contains("车型") && (headers.contains("核心定位") || headers.contains("定位"))) {
            log.info("🚗 检测到车型推荐表格");
            result.append(convertCarRecommendationTable(dataLines));
        } else if (headers.contains("能源类型") && headers.contains("官方价格")) {
            log.info("⚡ 检测到参数对比表格");
            result.append(convertParameterComparisonTable(dataLines));
        } else {
            log.info("📊 检测到通用表格");
            result.append(convertGenericTable(dataLines));
        }

        String converted = result.toString();
        log.info("✅ 表格转换结果长度: {}", converted.length());
        return converted;
    }

    /**
     * 转换车型推荐表格 - 增强调试版本
     */
    private String convertCarRecommendationTable(List<String> tableLines) {
        log.info("🚗 开始转换车型推荐表格，行数: {}", tableLines.size());

        StringBuilder result = new StringBuilder();
        List<String> headers = parseTableRow(tableLines.get(0));

        result.append("**推荐车型：**\n\n");

        int itemCount = 0;
        for (int i = 1; i < tableLines.size(); i++) {
            List<String> row = parseTableRow(tableLines.get(i));
            log.debug("📝 处理第{}行数据: {}", i, row);

            if (row.size() >= headers.size()) {
                String model = getCellValue(row, headers, "车型");
                String positioning = getCellValue(row, headers, "核心定位");
                if (positioning == null) positioning = getCellValue(row, headers, "定位");
                String website = getCellValue(row, headers, "官网");
                String price = getCellValue(row, headers, "落地价预估");
                if (price == null) price = getCellValue(row, headers, "价格");
                String recommendation = getCellValue(row, headers, "一句话推荐");
                String rating = getCellValue(row, headers, "推荐指数");

                log.debug("🔍 解析结果 - 车型: {}, 定位: {}, 价格: {}", model, positioning, price);

                if (model != null && !model.isEmpty()) {
                    itemCount++;
                    result.append(itemCount).append(". **").append(model).append("**");

                    if (positioning != null && !positioning.isEmpty()) {
                        result.append("：核心定位：").append(positioning);
                    }
                    if (website != null && !website.isEmpty()) {
                        result.append("，官网：").append(website);
                    }
                    if (price != null && !price.isEmpty()) {
                        result.append("，落地价预估：").append(price);
                    }
                    if (recommendation != null && !recommendation.isEmpty()) {
                        result.append("，").append(recommendation);
                    }
                    if (rating != null && !rating.isEmpty()) {
                        result.append("，推荐指数：").append(rating);
                    }
                    result.append("\n\n");
                }
            }
        }

        log.info("✅ 车型推荐表格转换完成，生成{}个推荐项", itemCount);

        if (itemCount == 0) {
            log.warn("❌ 没有成功转换任何推荐项，返回原始表格");
            return String.join("\n", tableLines) + "\n";
        }

        return result.toString();
    }

    /**
     * 转换参数对比表格
     */
    private String convertParameterComparisonTable(List<String> tableLines) {
        StringBuilder result = new StringBuilder();
        List<String> headers = parseTableRow(tableLines.get(0));

        for (int i = 1; i < tableLines.size(); i++) {
            List<String> row = parseTableRow(tableLines.get(i));
            if (row.size() >= headers.size()) {
                String model = getCellValue(row, headers, "车型");
                if (model != null && !model.isEmpty()) {
                    result.append("**").append(model).append("**\n");

                    for (String header : headers) {
                        if (!header.equals("车型")) {
                            String value = getCellValue(row, headers, header);
                            if (value != null && !value.isEmpty()) {
                                result.append("- ").append(header).append("：").append(value).append("\n");
                            }
                        }
                    }
                    result.append("\n");
                }
            }
        }

        return result.toString();
    }

    /**
     * 转换通用表格
     */
    private String convertGenericTable(List<String> tableLines) {
        StringBuilder result = new StringBuilder();
        List<String> headers = parseTableRow(tableLines.get(0));

        result.append("**相关信息：**\n\n");

        for (int i = 1; i < tableLines.size(); i++) {
            List<String> row = parseTableRow(tableLines.get(i));
            if (row.size() >= headers.size()) {
                StringBuilder rowText = new StringBuilder();
                for (int j = 0; j < headers.size(); j++) {
                    if (j < row.size() && !row.get(j).isEmpty()) {
                        if (j == 0) {
                            rowText.append("**").append(row.get(j)).append("**");
                        } else {
                            rowText.append("，").append(headers.get(j)).append("：").append(row.get(j));
                        }
                    }
                }
                if (rowText.length() > 0) {
                    result.append("- ").append(rowText).append("\n");
                }
            }
        }

        return result.toString();
    }

    /**
     * 解析表格行 - 修复版本
     */
    private List<String> parseTableRow(String tableLine) {
        List<String> cells = new ArrayList<>();

        // 先恢复保护标记
        String cleanLine = tableLine.replace("__PIPE_SPACE__", " |")
                .replace("__SPACE_PIPE__", "| ")
                .replace("__PIPE_DASH__", "|-")
                .replace("__DASH_PIPE__", "-|");

        // 使用-1保留空字符串，正确处理表格边界
        String[] parts = cleanLine.split("\\|", -1);

        for (int i = 0; i < parts.length; i++) {
            String cell = parts[i].trim();
            // 跳过完全空的行和表格分隔符
            if (!cell.isEmpty() && !isTableSeparator(cell)) {
                cells.add(cell);
            }
        }

        log.debug("解析表格行: {} -> {}", cleanLine, cells);
        return cells;
    }

    /**
     * 获取单元格值
     */
    private String getCellValue(List<String> row, List<String> headers, String headerName) {
        int index = headers.indexOf(headerName);
        if (index >= 0 && index < row.size()) {
            return row.get(index);
        }
        return null;
    }

    /**
     * 优化段落结构
     */
    private String optimizeParagraphStructure(String content) {
        if (content == null || content.isEmpty()) return content;

        // 合并多余空行
        content = content.replaceAll("\\n{3,}", "\n\n");

        // 确保标题后有适当的空行
        content = content.replaceAll("(### .+?)\\n(?!\\n)", "$1\n\n");

        // 确保列表项格式统一
        content = content.replaceAll("(\\d+\\.)\\s+", "$1 ");

        return content;
    }

    /**
     * 改进的激进清理算法 - 保护换行符
     */
    public String cleanContentImproved(String content) {
        if (content == null) return null;

        content = content.trim();
        if (content.isEmpty()) return content;

        log.info("🧹 开始内容清理，原始内容长度: {}", content.length());

        // 第一步：保护表格结构和换行符
        String protectedContent = protectTableStructures(content);
        log.debug("✅ 表格结构保护完成");

        // 第二步：删除中文字符之间的空格
        String noChineseSpaces = removeChineseSpacesImproved(protectedContent);
        log.debug("✅ 中文空格清理完成");

        // 第三步：清理多余换行，但保留表格间的空行
        String cleanedLineBreaks = cleanLineBreaksImproved(noChineseSpaces);
        log.debug("✅ 换行清理完成");

        // 第四步：恢复表格结构
        String finalContent = restoreTableStructures(cleanedLineBreaks);
        log.debug("✅ 表格结构恢复完成");

        log.info("🎉 内容清理完成，最终内容长度: {}", finalContent.length());
        return finalContent.trim();
    }

    /**
     * 保护表格结构 - 用占位符替换表格中的关键元素
     */
    private String protectTableStructures(String content) {
        if (content == null || content.isEmpty()) return content;

        String[] lines = content.split("\n");
        StringBuilder result = new StringBuilder();
        boolean inTable = false;

        for (String line : lines) {
            String trimmedLine = line.trim();

            // 检测表格行（包含 | 符号且不是表格分隔行）
            if (trimmedLine.contains("|") && !isTableSeparator(trimmedLine)) {
                inTable = true;
                // 保护表格行：用特殊标记保护表格管道符周围的空格
                String protectedLine = protectTableLine(line);
                result.append(protectedLine).append("\n");
            } else if (isTableSeparator(trimmedLine)) {
                // 表格分隔行：完全保留原样
                inTable = true;
                result.append(line).append("\n");
            } else {
                // 非表格行
                if (inTable) {
                    // 表格结束后的空行保留
                    if (trimmedLine.isEmpty()) {
                        result.append("\n");
                    }
                    inTable = false;
                }
                result.append(line).append("\n");
            }
        }

        return result.toString();
    }

    /**
     * 保护表格行中的格式
     */
    private String protectTableLine(String line) {
        // 用特殊标记保护表格管道符周围的格式
        String protectedLine = line.replace(" |", " __PIPE_SPACE__")
                .replace("| ", "__SPACE_PIPE__")
                .replace("|-", "__PIPE_DASH__")
                .replace("-|", "__DASH_PIPE__")
                .replace("|:", "__PIPE_COLON__")
                .replace(":|", "__COLON_PIPE__");
        return protectedLine;
    }

    /**
     * 恢复表格结构
     */
    private String restoreTableStructures(String content) {
        return content.replace("__PIPE_SPACE__", " |")
                .replace("__SPACE_PIPE__", "| ")
                .replace("__PIPE_DASH__", "|-")
                .replace("__DASH_PIPE__", "-|")
                .replace("__PIPE_COLON__", "|:")
                .replace("__COLON_PIPE__", ":|")
                .replace("__TABLE_PIPE__", "|");
    }

    /**
     * 判断是否为表格分隔行
     */
    private boolean isTableSeparator(String line) {
        return line.matches("^\\|?[\\s:|-]+\\|?[\\s:|-]+\\|?$") ||
                line.matches("^[:\\-\\s\\|]+$");
    }

    /**
     * 改进的中文空格删除
     */
    private String removeChineseSpacesImproved(String text) {
        if (text == null || text.isEmpty()) return text;

        // 保护区域内的内容不处理（如链接、代码等）
        String protectedText = protectSpecialAreas(text);

        // 删除中文字符之间的空格
        String noChineseSpaces = removeChineseCharacterSpaces(protectedText);

        // 恢复保护区域
        return restoreSpecialAreas(noChineseSpaces);
    }

    /**
     * 保护特殊区域（链接、代码等）
     */
    private String protectSpecialAreas(String text) {
        // 保护链接 [text](url)
        text = text.replaceAll("\\[([^\\]]+)\\]\\(([^)]+)\\)", "__LINK_START__$1__LINK_MID__$2__LINK_END__");

        // 保护表格保护标记
        text = text.replace("__PIPE_SPACE__", "__PROTECTED_PIPE_SPACE__");
        text = text.replace("__SPACE_PIPE__", "__PROTECTED_SPACE_PIPE__");
        text = text.replace("__PIPE_DASH__", "__PROTECTED_PIPE_DASH__");
        text = text.replace("__DASH_PIPE__", "__PROTECTED_DASH_PIPE__");

        return text;
    }

    /**
     * 恢复特殊区域
     */
    private String restoreSpecialAreas(String text) {
        text = text.replace("__PROTECTED_PIPE_SPACE__", "__PIPE_SPACE__");
        text = text.replace("__PROTECTED_SPACE_PIPE__", "__SPACE_PIPE__");
        text = text.replace("__PROTECTED_PIPE_DASH__", "__PIPE_DASH__");
        text = text.replace("__PROTECTED_DASH_PIPE__", "__DASH_PIPE__");
        text = text.replaceAll("__LINK_START__([^_]+)__LINK_MID__([^_]+)__LINK_END__", "[$1]($2)");

        return text;
    }

    /**
     * 删除中文字符间的空格
     */
    private String removeChineseCharacterSpaces(String text) {
        // 模式1：中文字符之间的空格
        String pattern1 = "([\\u4e00-\\u9fa5])\\s+([\\u4e00-\\u9fa5])";
        String step1 = text.replaceAll(pattern1, "$1$2");

        // 模式2：中文字符与数字之间的空格
        String pattern2 = "([\\u4e00-\\u9fa5])\\s+(\\d)";
        String step2 = step1.replaceAll(pattern2, "$1$2");

        // 模式3：数字与中文字符之间的空格
        String pattern3 = "(\\d)\\s+([\\u4e00-\\u9fa5])";
        String step3 = step2.replaceAll(pattern3, "$1$2");

        // 模式4：中文字符与英文字母之间的空格
        String pattern4 = "([\\u4e00-\\u9fa5])\\s+([a-zA-Z])";
        String step4 = step3.replaceAll(pattern4, "$1$2");

        // 模式5：英文字母与中文字符之间的空格
        String pattern5 = "([a-zA-Z])\\s+([\\u4e00-\\u9fa5])";
        String step5 = step4.replaceAll(pattern5, "$1$2");

        return step5;
    }

    /**
     * 改进的换行清理 - 保护必要的换行符
     */
    private String cleanLineBreaksImproved(String text) {
        if (text == null || text.isEmpty()) return text;

        String[] lines = text.split("\\r?\\n");
        StringBuilder result = new StringBuilder();

        int consecutiveEmptyLines = 0;
        boolean previousLineWasTable = false;

        for (int i = 0; i < lines.length; i++) {
            String line = lines[i];
            String trimmedLine = line.trim();

            boolean isTableLine = trimmedLine.contains("|") || isTableSeparator(trimmedLine);
            boolean isEmptyLine = trimmedLine.isEmpty();

            if (isEmptyLine) {
                consecutiveEmptyLines++;
                // 表格区域：最多保留1个空行作为分隔
                // 非表格区域：最多保留1个空行作为段落分隔
                if (consecutiveEmptyLines <= 1) {
                    result.append("\n");
                }
            } else {
                consecutiveEmptyLines = 0;

                // 如果是表格行且前一行不是表格，添加必要的空行
                if (isTableLine && !previousLineWasTable && result.length() > 0 &&
                        !result.toString().endsWith("\n\n")) {
                    result.append("\n");
                }

                result.append(line);
                if (i < lines.length - 1) {
                    result.append("\n");
                }
            }

            previousLineWasTable = isTableLine && !isEmptyLine;
        }

        return result.toString().trim();
    }

    /**
     * 主清理方法 - 使用改进算法
     */
    private String cleanContent(String content) {
        return cleanContentImproved(content);
    }

    // 其他方法保持不变...
    @Async
    @Transactional
    public void consumeStream(Long sessionId, String redisKey) {
        String lastId = "0-0";
        log.info("🚀 开始监听 Redis Stream: {}", redisKey);

        while (true) {
            try {
                List<MapRecord<String, Object, Object>> records =
                        redisTemplate.opsForStream().read(StreamOffset.create(redisKey, ReadOffset.from(lastId)));

                if (records == null || records.isEmpty()) {
                    Thread.sleep(200);
                    continue;
                }

                for (MapRecord<String, Object, Object> record : records) {
                    Map<Object, Object> map = record.getValue();
                    String content = map.get("message") != null ? map.get("message").toString() : null;

                    if (content != null) {
                        // 应用改进的清理算法
                        content = cleanContentImproved(content);
                        log.debug("✅ 清理后内容: {}", content.substring(0, Math.min(100, content.length())));
                    }

                    if (content != null && !content.isEmpty() && !"__END__".equals(content)) {
                        saveLlmOutput(sessionId, content);
                    }

                    lastId = record.getId().getValue();

                    if ("__END__".equals(map.get("message"))) {
                        finalizeSession(sessionId);
                        redisTemplate.delete(redisKey);
                        log.info("🏁 Redis Stream 完成，删除 key={}", redisKey);
                        return;
                    }
                }
            } catch (Exception e) {
                log.error("❌ LlmOutputConsumer 出错: {}", e.getMessage(), e);
            }
        }
    }

    @Transactional
    public void saveLlmOutput(Long sessionId, String content) {
        if (content == null || content.isEmpty() || "__END__".equals(content)) {
            return;
        }

        // 在保存前也进行内容清理
        content = cleanContentImproved(content);

        if (content.isEmpty()) {
            return;
        }

        LlmOutputs record = new LlmOutputs();
        record.setSessionid(sessionId);
        record.setContent(content);
        llmOutputsRepository.save(record);
        log.debug("💾 保存LLM输出: sessionId={}, 内容长度={}", sessionId, content.length());
    }

    @Async
    public void streamToEmitter(String redisKey, SseEmitter emitter) {
        String lastId = "0-0";
        log.info("🚀 开始 SSE 监听 Redis Stream: {}", redisKey);

        try {
            while (true) {
                List<MapRecord<String, Object, Object>> records =
                        redisTemplate.opsForStream().read(StreamOffset.create(redisKey, ReadOffset.from(lastId)));

                if (records == null || records.isEmpty()) {
                    Thread.sleep(200);
                    continue;
                }

                for (MapRecord<String, Object, Object> record : records) {
                    Map<Object, Object> map = record.getValue();
                    String content = map.get("message") != null ? map.get("message").toString() : null;

                    if (content != null) {
                        // 应用改进的清理算法
                        content = cleanContentImproved(content);
                    }

                    if (content != null && !content.isEmpty() && !"__END__".equals(content)) {
                        emitter.send(SseEmitter.event().data(content));
                    }

                    lastId = record.getId().getValue();

                    if ("__END__".equals(map.get("message"))) {
                        emitter.complete();
                        redisTemplate.delete(redisKey);
                        log.info("🏁 SSE Stream 完成，删除 key={}", redisKey);
                        return;
                    }
                }
            }
        } catch (Exception e) {
            log.error("❌ SSE Stream 出错: {}", e.getMessage(), e);
            emitter.completeWithError(e);
        }
    }

    @Transactional
    public void finalizeSession(Long sessionId) {
        try {
            // 聚合所有内容
            StringBuilder sb = new StringBuilder();
            llmOutputsRepository.findBySessionidOrderByCreatedAtAsc(sessionId)
                    .stream()
                    .map(LlmOutputs::getContent)
                    .filter(c -> c != null && !c.isBlank())
                    .forEach(c -> sb.append(c).append(" "));

            String finalAnswer = sb.toString().trim();

            // 使用完整的格式化逻辑
            finalAnswer = formatForFinalAnswer(finalAnswer);

            sessionsRepository.updateAnswerBySessionid(sessionId, finalAnswer);
            log.info("✅ 最终答案处理完成: sessionId={}, 内容长度={}", sessionId, finalAnswer.length());

            // 清理临时记录
            llmOutputsRepository.deleteBySessionid(sessionId);
            log.info("🧹 已清理临时 llm_outputs: sessionid={}", sessionId);

        } catch (Exception e) {
            log.error("⚠️ 清理 llm_outputs 失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 测试方法 - 用于验证算法效果
     */
    public void testAlgorithm() {
        // 先测试一个简单的表格
        testSimpleTable();

        System.out.println("\n" + "=".repeat(80) + "\n");

        // 再测试简化完整内容
        testSimplifiedFullContent();

        System.out.println("\n" + "=".repeat(80) + "\n");

        // 最后测试原始完整内容
        testFullContent();
    }

    /**
     * 测试简单表格
     */
    private void testSimpleTable() {
        String simpleContent = "### 推荐车型\n| 车型 | 核心定位 | 官网 | 落地价预估 |\n| :--- | :--- | :--- | :--- |\n| **测试车** | 测试定位 | 点此访问 | 10万元 |";

        log.info("=== 简单表格测试 ===");
        log.info("原始内容:\n{}", simpleContent);

        String cleaned = cleanContentImproved(simpleContent);
        log.info("清理后内容:\n{}", cleaned);

        String finalFormatted = formatForFinalAnswer(cleaned);
        log.info("最终响应格式化:\n{}", finalFormatted);
    }

    /**
     * 测试完整内容 - 修复版本
     */
    private void testFullContent() {
        // 修复测试内容，确保包含正确的换行符
        String testContent = "您好 ！ 感谢您的提问 。 根据您20 - 30万元的预算以及对丰田品牌的偏好 ， 我们为您精心筛选了3款目前市场上极具竞争力的丰田车型 。 它们分别覆盖了SUV 、 轿车等 不同品类 ， 并在混 动技术上有突出优势 。 \n--- \n### 1 . 核心推荐摘要  \n| 车型  | 核心定位  | 官网  | 落地价 预估  | 一句话推荐  | 推荐指数  |  \n| : ---  | : ---  | : ---  | : ---  | : ---  | : ---  |  \n| ** 广汽 丰田汉 兰达 双擎 **  | 大七 座家用SUV标杆  | [ 点此 访问 ]( https :// www .g ac -t oy ota .com .cn / ve hicles /h igh lander /)  | 28 - 35万元  | \" 空间魔术师 ， 全家出 行的全能保障 。\"  | ★ ★★★★  |  \n| ** 一汽 丰田皇 冠陆 放 **  | 豪华大 七座SUV  | [ 点此 访问 ]( https :// www . ft ms .com .cn / ve hicles /c rown kl ug er /index .html )  | 29 - 36万元  | \" 汉兰 达的 姊妹车 ， 气质更 豪华 ， 体验更 静谧 。\"  | ★ ★★ ★ ☆  |  \n| ** 广汽 丰田凯 美瑞 双擎 **  | 中高级轿车价值旗舰  | [ 点此 访问 ]( https :// www .g ac -t oy ota .com .cn / ve hicles /c am ry /)  | 22 - 26万元  | \" 省心 省油的终极选择 ， 驾驶质感与 经济性的完美平衡 。\"  | ★ ★★ ★ ☆  |";

        log.info("=== 完整内容测试 ===");
        log.info("原始内容:\n{}", testContent);
        log.info("原始内容长度: {}", testContent.length());

        String cleaned = cleanContentImproved(testContent);
        log.info("清理后内容:\n{}", cleaned);
        log.info("清理后内容长度: {}", cleaned.length());

        String finalFormatted = formatForFinalAnswer(cleaned);
        log.info("最终响应格式化:\n{}", finalFormatted);
        log.info("最终内容长度: {}", finalFormatted.length());

        // 添加调试信息
        debugContentStructure(testContent);
    }

    /**
     * 调试内容结构
     */
    private void debugContentStructure(String content) {
        log.info("=== 内容结构调试 ===");
        String[] lines = content.split("\\r?\\n");
        log.info("总行数: {}", lines.length);

        for (int i = 0; i < lines.length; i++) {
            String line = lines[i].trim();
            if (!line.isEmpty()) {
                log.info("行 {}: {} (长度: {})", i,
                        line.length() > 50 ? line.substring(0, 50) + "..." : line,
                        line.length());

                // 检查是否包含表格相关特征
                if (line.contains("|")) {
                    log.info("  📊 包含表格管道符");
                }
                if (isTableHeader(line)) {
                    log.info("  🎯 检测为表格表头");
                }
                if (isTableSeparator(line)) {
                    log.info("  📏 检测为表格分隔行");
                }
            }
        }
    }

    /**
     * 分步调试方法
     */
    private void debugStepByStep(String content) {
        log.info("=== 分步调试 ===");

        // 1. 基础清理
        String step1 = cleanContentImproved(content);
        log.info("步骤1 - 基础清理后:\n{}", step1);

        // 2. 表格转换
        String step2 = convertAllTablesToNaturalLanguage(step1);
        log.info("步骤2 - 表格转换后:\n{}", step2);

        // 3. 优化段落
        String step3 = optimizeParagraphStructure(step2);
        log.info("步骤3 - 段落优化后:\n{}", step3);
    }

    /**
     * 测试简化完整内容
     */
    private void testSimplifiedFullContent() {
        // 使用更简单的格式，确保换行符正确
        String testContent =
                "您好！感谢您的提问。根据您20-30万元的预算以及对丰田品牌的偏好，我们为您精心筛选了3款目前市场上极具竞争力的丰田车型。\n\n" +
                        "### 1. 核心推荐摘要\n" +
                        "| 车型 | 核心定位 | 官网 | 落地价预估 | 一句话推荐 | 推荐指数 |\n" +
                        "| :--- | :--- | :--- | :--- | :--- | :--- |\n" +
                        "| **广汽丰田汉兰达双擎** | 大七座家用SUV标杆 | [点此访问](https://www.gac-toyota.com.cn/vehicles/highlander/) | 28-35万元 | \"空间魔术师，全家出行的全能保障。\" | ★★★★ |\n" +
                        "| **一汽丰田皇冠陆放** | 豪华大七座SUV | [点此访问](https://www.ftms.com.cn/vehicles/crownkluger/index.html) | 29-36万元 | \"汉兰达的姊妹车，气质更豪华，体验更静谧。\" | ★★★☆ |\n" +
                        "| **广汽丰田凯美瑞双擎** | 中高级轿车价值旗舰 | [点此访问](https://www.gac-toyota.com.cn/vehicles/camry/) | 22-26万元 | \"省心省油的终极选择，驾驶质感与经济性的完美平衡。\" | ★★★☆ |";

        log.info("=== 简化完整内容测试 ===");
        log.info("原始内容:\n{}", testContent);

        String cleaned = cleanContentImproved(testContent);
        log.info("清理后内容:\n{}", cleaned);

        String finalFormatted = formatForFinalAnswer(cleaned);
        log.info("最终响应格式化:\n{}", finalFormatted);
    }

    /**
     * 简单测试方法
     */
    public void testSimpleCase() {
        String simpleContent = "您好 ！ 这是一 个测试 。 | 车型 | 价格 | | --- | --- | | 测试车 | 10 万元 |";
        log.info("=== 简单测试 ===");
        log.info("原始内容:\n{}", simpleContent);

        String cleaned = cleanContentImproved(simpleContent);
        log.info("清理后:\n{}", cleaned);

        String formatted = formatForFinalAnswer(cleaned);
        log.info("格式化后:\n{}", formatted);
    }

    public static void main(String[] args) {
        // 创建实例并运行测试
        LlmOutputConsumer consumer = new LlmOutputConsumer();

        // 运行完整测试
        consumer.testAlgorithm();
    }
}